package com.android.progressdemo;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

import java.text.DecimalFormat;

public class InfoView extends View {
    private static final long ANIMATION_DURATION = 1500L;
    private static final DecimalFormat df = new DecimalFormat("0.0");
    // 绘制边框
    private Paint paintStroke;
    // 绘制填充
    private Paint paintFill;
    // Path轨迹对象
    private final Path path = new Path();
    // 底部小箭头的高度，单位像素
    private float mArrowHeight;
    // 绘制百分比标签
    private Paint paintInfoLabel;
    // 绘制百分比
    private Paint paintInfoProgress;
    // 绘制百分号
    private Paint paintInfoPercent;
    // 等边三角形边长的一半
    private float c;
    // 当前百分比
    private float currentPercent;
    // 圆弧的半径
    private float radius;
    // 左圆弧的矩形范围
    private final RectF leftRect = new RectF();
    // 右圆弧的矩形范围
    private final RectF rightRect = new RectF();

    private String infoTextLabel = " 进度 ";
    // 标签的宽度，单位像素
    private float infoTextLabelWidth;

    private String infoTextPercent = " % ";
    // 百分号的宽度，单位像素
    private float infoTextPercentWidth;

    public InfoView(Context context) {
        this(context, null);
    }

    public InfoView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public InfoView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        paintFill = new Paint();
        paintFill.setAntiAlias(true);
        // 弹窗的背景色
        paintFill.setColor(Color.parseColor("#C87A7C"));
        paintFill.setStyle(Paint.Style.FILL);
        // 弹窗的背景色的透明度
        paintFill.setAlpha(100);

        paintStroke = new Paint();
        paintStroke.setAntiAlias(true);
        paintStroke.setStyle(Paint.Style.STROKE);
        paintStroke.setStrokeWidth(4);
        paintStroke.setColor(Color.RED);

        paintInfoLabel = new Paint();
        paintInfoLabel.setAntiAlias(true);
        paintInfoLabel.setColor(Color.BLACK);
        paintInfoLabel.setTextSize(Utils.sp2px(context, 14));

        paintInfoProgress = new Paint();
        paintInfoProgress.setAntiAlias(true);
        paintInfoProgress.setColor(Color.RED);
        paintInfoProgress.setTextSize(Utils.sp2px(context, 20));
        paintInfoProgress.setTypeface(Typeface.DEFAULT_BOLD);

        paintInfoPercent = new Paint();
        paintInfoPercent.setAntiAlias(true);
        paintInfoPercent.setColor(Color.BLACK);
        paintInfoPercent.setTextSize(Utils.sp2px(context, 14));

        // 底部箭头的高度
        mArrowHeight = Utils.dp2px(context, 6);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        radius = (h - mArrowHeight - paintStroke.getStrokeWidth() / 2) / 2;
        double rad = 30 * Math.PI / 180.0;
        c = (float) (Math.tan(rad) * mArrowHeight);
        infoTextLabelWidth = getTextLabelWidth();
        infoTextPercentWidth = getTextPercentWidth();
    }

    // 获取当前文字
    private String getText() {
        return df.format(this.currentPercent * 100);
    }

    // 计算文字标签的宽度
    private float getTextLabelWidth() {
        String text = infoTextLabel;
        return paintInfoLabel.measureText(text, 0, text.length());
    }

    // 计算文字百分号的宽度
    private float getTextPercentWidth() {
        String text = infoTextPercent;
        return paintInfoPercent.measureText(text, 0, text.length());
    }

    // 计算文字百分比的宽度
    private float getTextProgressWidth() {
        String text = getText();
        return paintInfoProgress.measureText(text, 0, text.length());
    }

    // 计算所有文字的宽度
    private float getInfoTextWidth() {
        return infoTextLabelWidth + getTextProgressWidth() + infoTextPercentWidth;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 计算所有文字的宽度
        float textWidth = getInfoTextWidth();
        // 绘制Path
        float x = drawPath(canvas, textWidth);
        // 绘制文字
        drawText(canvas, x);
    }

    private float drawPath(Canvas canvas, float textWidth) {

        path.reset();

        // 箭头活动范围，对应的距离长度是：distance
        float distance = getWidth() - 2 * radius - 2 * c;
        // 箭头左边的线段的长度
        float leftDistance = (textWidth - 2 * c) * currentPercent;

        // 1
        float firstX = radius + c + (currentPercent * distance);
        float firstY = getHeight();
        path.moveTo(firstX, firstY);

        // 2
        float secondX = firstX - c;
        float secondY = getHeight() - mArrowHeight;
        path.lineTo(secondX, secondY);

        // 3
        float thirdX = firstX - c - leftDistance;
        float thirdY = getHeight() - mArrowHeight;
        path.lineTo(thirdX, thirdY);

        // 4
        float left = firstX - c - leftDistance - radius;
        float top = 0;
        float right = firstX - c - leftDistance + radius;
        float bottom = getHeight() - mArrowHeight;
        leftRect.set(left, top, right, bottom);
        path.arcTo(leftRect, 90, 180);

        // 5
        float fourthX = firstX - c - leftDistance + textWidth;
        float fourthY = 0;
        path.lineTo(fourthX, fourthY);

        //6
        float left2 = firstX - c - leftDistance + textWidth - radius;
        float top2 = 0;
        float right2 = firstX - c - leftDistance + textWidth + radius;
        float bottom2 = getHeight() - mArrowHeight;
        rightRect.set(left2, top2, right2, bottom2);
        path.arcTo(rightRect, -90, 180);

        // 7
        float fifthX = firstX + c;
        float fifthY = getHeight() - mArrowHeight;
        path.lineTo(fifthX, fifthY);
        path.close();

        //绘制轨迹-填充
        canvas.drawPath(path, paintFill);
        //绘制轨迹-边框
        canvas.drawPath(path, paintStroke);

        return thirdX;
    }

    /**
     * 绘制文字
     *
     * @param canvas 画布
     * @param x      x坐标
     */
    private void drawText(Canvas canvas, float x) {
        // 绘制文字，百分比
        Paint.FontMetricsInt fontMetricsInt1 = paintInfoLabel.getFontMetricsInt();
        float dy1 = (fontMetricsInt1.bottom - fontMetricsInt1.top) / 2f - fontMetricsInt1.bottom;
        float baseLine = (getHeight() - mArrowHeight) / 2f + dy1;
        canvas.drawText(infoTextLabel, x, baseLine, paintInfoLabel);

        // 绘制文字，百分比
        Paint.FontMetricsInt fontMetricsInt2 = paintInfoProgress.getFontMetricsInt();
        float dy2 = (fontMetricsInt2.bottom - fontMetricsInt2.top) / 2f - fontMetricsInt2.bottom;
        float baseLine2 = (getHeight() - mArrowHeight) / 2f + dy2;
        canvas.drawText(getText(), x + infoTextLabelWidth, baseLine2, paintInfoProgress);

        // 绘制文字，百分比
        Paint.FontMetricsInt fontMetricsInt3 = paintInfoPercent.getFontMetricsInt();
        float dy3 = (fontMetricsInt3.bottom - fontMetricsInt3.top) / 2f - fontMetricsInt3.bottom;
        float baseLine3 = (getHeight() - mArrowHeight) / 2f + dy3;
        canvas.drawText(infoTextPercent, x + infoTextLabelWidth + getTextProgressWidth(), baseLine3, paintInfoPercent);
    }


    /**
     * 设置当前进度的数据，带动画
     *
     * @param progress 百分比
     */
    public void setProgressWithAnim(float progress) {
        ValueAnimator animator = ValueAnimator.ofFloat(0, progress).setDuration(ANIMATION_DURATION);
        animator.addUpdateListener(animation -> {
            currentPercent = (float) animation.getAnimatedValue() / 100.0f;
            invalidate();
        });
        animator.start();
    }
}
